package com.lboyang.core.spring;

import com.lboyang.core.annotation.NnziScan;
import com.lboyang.core.annotation.NnziService;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.StandardAnnotationMetadata;
import org.springframework.stereotype.Component;

/**
 * @Description
 *      向 IOC 容器注册 BeanDefinition
 * @Date 2021/9/13 16:50
 * @author: A.iguodala
 */
@Slf4j
public class CustomScannerRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {

    /**
     * 默认包扫描路径
     */
    private static final String SPRING_BEAN_BASE_PACKAGE = "com.lboyang";

    /**
     * 默认包名
     */
    private static final String BASE_PACKAGE_ATTRIBUTE_NAME = "basePackage";

    /**
     * 资源加载器
     */
    private ResourceLoader resourceLoader;

    /**
     * 通过实现 ResourceLoaderAware 接口可以注入资源加载类
     * @param resourceLoader
     */
    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;

    }

    /**
     * 通过实现 ImportBeanDefinitionRegistrar
     * 向 IOC 容器注册 BeanDefinition
     * @param annotationMetadata
     * @param beanDefinitionRegistry
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
        // 获取对应包扫描类的属性和值
        AnnotationAttributes rpcScanAnnotationAttributes = AnnotationAttributes.fromMap(annotationMetadata.getAnnotationAttributes(NnziScan.class.getName()));
        String[] rpcScanBasePackages = new String[0];
        if (rpcScanAnnotationAttributes != null) {
            // 获取对应RPC相关包
            rpcScanBasePackages = rpcScanAnnotationAttributes.getStringArray(BASE_PACKAGE_ATTRIBUTE_NAME);
        }
        if (rpcScanBasePackages.length == 0) {
            rpcScanBasePackages = new String[]{((StandardAnnotationMetadata) annotationMetadata).getIntrospectedClass().getPackage().getName()};
        }
        // 得到 NnziService 注解，表示需要暴露服务【启动 Netty 服务器，并向注册中心注册服务】
        CustomScanner rpcServiceScanner = new CustomScanner(beanDefinitionRegistry, NnziService.class);
        // 获取 Component 注解保证注册到容器
        CustomScanner springBeanScanner = new CustomScanner(beanDefinitionRegistry, Component.class);
        if (resourceLoader != null) {
            rpcServiceScanner.setResourceLoader(resourceLoader);
            springBeanScanner.setResourceLoader(resourceLoader);
        }
        int springBeanAmount = springBeanScanner.scan(SPRING_BEAN_BASE_PACKAGE);
        log.info("springBeanScanner扫描的数量 [{}]", springBeanAmount);
        int rpcServiceCount = rpcServiceScanner.scan(rpcScanBasePackages);
        log.info("rpcServiceScanner扫描的数量 [{}]", rpcServiceCount);

    }

}
